home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / benchmarks / itc / sranlib / sranlib.c < prev   
Encoding:
C/C++ Source or Header  |  1989-08-30  |  8.7 KB  |  385 lines

  1. /*
  2.  * Copyright (c) 1980 Regents of the University of California.
  3.  * All rights reserved.  The Berkeley software License Agreement
  4.  * specifies the terms and conditions for redistribution.
  5.  *
  6.  * Revisions for SPUR: Copyright (c) 1987 Regents of the University of 
  7.  *       California.
  8.  * All rights reserved.
  9.  *
  10.  * Revised by P. N. Hilfinger
  11.  */
  12.  
  13. #ifndef lint
  14. char copyright[] =
  15. "@(#) Copyright (c) 1980, 1987 Regents of the University of California.\n\
  16.  All rights reserved.\n";
  17. #endif not lint
  18.  
  19. #ifndef lint
  20. static char rcsid[] = "$Header: ranlib.c,v 1.3 88/07/06 11:54:01 hilfingr Exp $";
  21. #endif not lint
  22.  
  23. /*
  24.  * ranlib - create table of contents for archive; string table version
  25.  */
  26. #include <sys/types.h>
  27. #include <ar.h>
  28. #include <ranlib.h>
  29. #include <strings.h>
  30. #include "a.out.h"
  31. #include <stdio.h>
  32.  
  33. extern char *sprintf();
  34. extern long lseek();
  35.  
  36. struct    ar_hdr    archdr;
  37. #define    OARMAG 0177545
  38. long    arsize;
  39. struct    exec    exp;
  40. FILE    *fi, *fo;
  41. long    off, oldoff;
  42. long    atol(), ftell();
  43. #define TABSZ    3000
  44. int    tnum;
  45. #define    STRTABSZ    30000
  46. int    tssiz;
  47. char    *strtab;
  48. int    ssiz;
  49. int    new;
  50. char    tempnm[] = "__.SYMDEF";
  51. char    firstname[17];
  52. void    stash();
  53. char *malloc(), *calloc();
  54.  
  55. /*
  56.  * table segment definitions
  57.  */
  58. char    *segalloc();
  59. void    segclean();
  60. struct    tabsegment {
  61.     struct tabsegment    *pnext;
  62.     unsigned        nelem;
  63.     struct ranlib        tab[TABSZ];
  64. } tabbase, *ptabseg;
  65. struct    strsegment {
  66.     struct strsegment    *pnext;
  67.     unsigned        nelem;
  68.     char            stab[STRTABSZ];
  69. } strbase, *pstrseg;
  70.  
  71. main(argc, argv)
  72. char **argv;
  73. {
  74.     char cmdbuf[BUFSIZ];
  75.     /* magbuf must be an int array so it is aligned on an int-ish
  76.        boundary, so that we may access its first word as an int! */
  77.     int magbuf[(SARMAG+sizeof(int))/sizeof(int)];
  78.     register int just_touch = 0;
  79.     register struct tabsegment *ptab;
  80.     register struct strsegment *pstr;
  81.  
  82.     /* check for the "-t" flag" */
  83.     if (argc > 1 && strcmp(argv[1], "-t") == 0) {
  84.         just_touch++;
  85.         argc--;
  86.         argv++;
  87.     }
  88.  
  89.     --argc;
  90.     while(argc--) {
  91.         fi = fopen(*++argv,"r");
  92.         if (fi == NULL) {
  93.             (void) fprintf(stderr, "ranlib: cannot open %s\n", *argv);
  94.             continue;
  95.         }
  96.         off = SARMAG;
  97.         (void) fread((char *)magbuf, 1, SARMAG, fi);
  98.         if (strncmp((char *)magbuf, ARMAG, SARMAG)) {
  99.             if (magbuf[0] == OARMAG)
  100.                 (void) fprintf(stderr, "old format ");
  101.             else
  102.                 (void) fprintf(stderr, "not an ");
  103.             (void) fprintf(stderr, "archive: %s\n", *argv);
  104.             continue;
  105.         }
  106.         if (just_touch) {
  107.             register int    len;
  108.  
  109.             (void) fseek(fi, (long) SARMAG, 0);
  110.             if (fread(cmdbuf, sizeof archdr.ar_name, 1, fi) != 1) {
  111.                 (void) fprintf(stderr, "malformed archive: %s\n",
  112.                     *argv);
  113.                 continue;
  114.             }
  115.             len = strlen(tempnm);
  116.             if (bcmp(cmdbuf, tempnm, len) != 0 ||
  117.                 cmdbuf[len] != ' ') {
  118.                 (void) fprintf(stderr, "no symbol table: %s\n", *argv);
  119.                 continue;
  120.             }
  121.             (void) fclose(fi);
  122.             fixdate(*argv);
  123.             continue;
  124.         }
  125.         (void) fseek(fi, 0L, 0);
  126.         new = tssiz = tnum = 0;
  127.         segclean();
  128.         if (nextel(fi) == 0) {
  129.             (void) fclose(fi);
  130.             continue;
  131.         }
  132.         do {
  133.             long o;
  134.             register n;
  135.             struct nlist sym;
  136.  
  137.             (void) fread((char *)&exp, 1, sizeof(struct exec), fi);
  138.             if (N_BADMAG(exp))
  139.                 continue;
  140.             if (!strncmp(tempnm, archdr.ar_name, sizeof(archdr.ar_name)))
  141.                 continue;
  142.             if (exp.a_syms == 0) {
  143.                 (void) fprintf(stderr, "ranlib: warning: %s(%s): no symbol table\n", *argv, archdr.ar_name);
  144.                 continue;
  145.             }
  146.             o = N_STROFF(exp) - sizeof (struct exec);
  147.             if (ftell(fi)+o+sizeof(ssiz) >= off) {
  148.                 (void) fprintf(stderr, "ranlib: warning: %s(%s): old format .o file\n", *argv, archdr.ar_name);
  149.                 continue;
  150.             }
  151.             (void) fseek(fi, o, 1);
  152.             (void) fread((char *)&ssiz, 1, sizeof (ssiz), fi);
  153.             if (ssiz < sizeof ssiz){
  154.                 /* sanity check */
  155.                 (void) fprintf(stderr, "ranlib: warning: %s(%s): mangled string table\n", *argv, archdr.ar_name);
  156.                 continue;
  157.             }
  158.             strtab = (char *)calloc(1, (unsigned int) ssiz);
  159.             if (strtab == 0) {
  160.                 (void) fprintf(stderr, "ranlib: ran out of memory\n");
  161.                 exit(1);
  162.             }
  163.             (void) fread(strtab+sizeof(ssiz), ssiz - sizeof(ssiz), 1, fi);
  164.             (void) fseek(fi,(long) -(exp.a_syms+ssiz), 1);
  165.             n = exp.a_syms / sizeof(struct nlist);
  166.             while (--n >= 0) {
  167.                 (void) fread((char *)&sym, 1, sizeof(sym), fi);
  168.                 if (sym.n_un.n_strx == 0)
  169.                     continue;
  170.                 sym.n_un.n_name = strtab + sym.n_un.n_strx;
  171.                 if ((sym.n_type&N_EXT) != 0 
  172.                     && (sym.n_type&N_TYPE) != N_UNDF
  173.                     && (sym.n_type&N_STAB) == 0) {
  174.                     stash(&sym);
  175.                 }
  176.             }
  177.             free(strtab);
  178.         } while(nextel(fi));
  179.         new = fixsize();
  180.         (void) fclose(fi);
  181.         fo = fopen(tempnm, "w");
  182.         if(fo == NULL) {
  183.             (void) fprintf(stderr, "can't create temporary\n");
  184.             exit(1);
  185.         }
  186.         tnum *= sizeof (struct ranlib);
  187.         (void) fwrite((char *) &tnum, 1, sizeof (tnum), fo);
  188.         tnum /= sizeof (struct ranlib);
  189.         ptab = &tabbase;
  190.         do {
  191.             (void) fwrite((char *)ptab->tab, (int) ptab->nelem,
  192.                 sizeof(struct ranlib), fo);
  193.         } while (ptab = ptab->pnext);
  194.         (void) fwrite((char *) &tssiz, 1, sizeof (tssiz), fo);
  195.         pstr = &strbase;
  196.         do {
  197.             (void) fwrite(pstr->stab, (int) pstr->nelem, 1, fo);
  198.             tssiz -= pstr->nelem;
  199.         } while (pstr = pstr->pnext);
  200.         /* pad with nulls */
  201.         while (tssiz--) putc('\0', fo);
  202.         (void) fclose(fo);
  203.         if(new)
  204.             (void) sprintf(cmdbuf, "ar rlb %s %s %s\n", firstname, *argv, tempnm);
  205.         else
  206.             (void) sprintf(cmdbuf, "ar rl %s %s\n", *argv, tempnm);
  207.         if(system(cmdbuf))
  208.             (void) fprintf(stderr, "ranlib: ``%s'' failed\n", cmdbuf);
  209.         else
  210.             fixdate(*argv);
  211.         (void) unlink(tempnm);
  212.     }
  213.     exit(0);
  214. }
  215.  
  216. nextel(af)
  217. FILE *af;
  218. {
  219.     register r;
  220.     register char *cp;
  221.  
  222.     oldoff = off;
  223.     (void) fseek(af, off, 0);
  224.     r = fread((char *)&archdr, 1, sizeof(struct ar_hdr), af);
  225.     if (r != sizeof(struct ar_hdr))
  226.         return(0);
  227.     for (cp=archdr.ar_name; cp < & archdr.ar_name[sizeof(archdr.ar_name)]; cp++)
  228.         if (*cp == ' ')
  229.             *cp = '\0';
  230.     arsize = atol(archdr.ar_size);
  231.     if (arsize & 1)
  232.         arsize++;
  233.     off = ftell(af) + arsize;
  234.     return(1);
  235. }
  236.  
  237. void
  238. stash(s)
  239.     struct nlist *s;
  240. {
  241.     register char *cp;
  242.     register char *strtab;
  243.     register strsiz;
  244.     register struct ranlib *tab;
  245.     register tabsiz;
  246.  
  247.     if (ptabseg->nelem >= TABSZ) {
  248.         /* allocate a new symbol table segment */
  249.         ptabseg = ptabseg->pnext =
  250.             (struct tabsegment *) segalloc(sizeof(struct tabsegment));
  251.         ptabseg->pnext = NULL;
  252.         ptabseg->nelem = 0;
  253.     }
  254.     tabsiz = ptabseg->nelem;
  255.     tab = ptabseg->tab;
  256.  
  257.     if (pstrseg->nelem >= STRTABSZ) {
  258.         /* allocate a new string table segment */
  259.         pstrseg = pstrseg->pnext =
  260.             (struct strsegment *) segalloc(sizeof(struct strsegment));
  261.         pstrseg->pnext = NULL;
  262.         pstrseg->nelem = 0;
  263.     }
  264.     strsiz = pstrseg->nelem;
  265.     strtab = pstrseg->stab;
  266.  
  267.     tab[tabsiz].ran_un.ran_strx = tssiz;
  268.     tab[tabsiz].ran_off = oldoff;
  269. redo:
  270.     for (cp = s->n_un.n_name; strtab[strsiz++] = *cp++;)
  271.         if (strsiz >= STRTABSZ) {
  272.             /* allocate a new string table segment */
  273.             pstrseg = pstrseg->pnext =
  274.                 (struct strsegment *) segalloc(sizeof(struct strsegment));
  275.             pstrseg->pnext = NULL;
  276.             strsiz = pstrseg->nelem = 0;
  277.             strtab = pstrseg->stab;
  278.             goto redo;
  279.         }
  280.  
  281.     tssiz += strsiz - pstrseg->nelem; /* length of the string */
  282.     pstrseg->nelem = strsiz;
  283.     tnum++;
  284.     ptabseg->nelem++;
  285. }
  286.  
  287. /* allocate a zero filled segment of size bytes */
  288. char *
  289. segalloc(size)
  290. unsigned size;
  291. {
  292.     char *pseg = NULL;
  293.  
  294.     pseg = malloc(size);
  295.     if (pseg == NULL) {
  296.         (void) fprintf(stderr, "ranlib: ran out of memeory\n");
  297.         exit(1);
  298.     }
  299.     return(pseg);
  300. }
  301.  
  302. /* free segments */
  303. void
  304. segclean()
  305. {
  306.     register struct tabsegment *ptab;
  307.     register struct strsegment *pstr;
  308.  
  309.     /*
  310.      * symbol table
  311.      *
  312.      * The first entry is static.
  313.      */
  314.     ptabseg = &tabbase;
  315.     ptab = ptabseg->pnext;
  316.     while (ptabseg = ptab) {
  317.         ptab = ptabseg->pnext;
  318.         free((char *)ptabseg);
  319.     }
  320.     ptabseg = &tabbase;
  321.     ptabseg->pnext = NULL;
  322.     ptabseg->nelem = 0;
  323.  
  324.     /*
  325.      * string table
  326.      *
  327.      * The first entry is static.
  328.      */
  329.     pstrseg = &strbase;
  330.     pstr = pstrseg->pnext;
  331.     while (pstrseg = pstr) {
  332.         pstr = pstrseg->pnext;
  333.         free((char *)pstrseg);
  334.     }
  335.     pstrseg = &strbase;
  336.     pstrseg->pnext = NULL;
  337.     pstrseg->nelem = 0;
  338. }
  339.  
  340. fixsize()
  341. {
  342.     int i;
  343.     off_t offdelta;
  344.     register struct tabsegment *ptab;
  345.  
  346.     if (tssiz&1)
  347.         tssiz++;
  348.     offdelta = sizeof(archdr) + sizeof (tnum) + tnum * sizeof(struct ranlib) +
  349.         sizeof (tssiz) + tssiz;
  350.     off = SARMAG;
  351.     (void) nextel(fi);
  352.     if(strncmp(archdr.ar_name, tempnm, sizeof (archdr.ar_name)) == 0) {
  353.         new = 0;
  354.         offdelta -= sizeof(archdr) + arsize;
  355.     } else {
  356.         new = 1;
  357.         (void) strncpy(firstname, archdr.ar_name, sizeof(archdr.ar_name));
  358.     }
  359.     ptab = &tabbase;
  360.     do {
  361.         for (i = 0; i < ptab->nelem; i++)
  362.             ptab->tab[i].ran_off += offdelta;
  363.     } while (ptab = ptab->pnext);
  364.     return(new);
  365. }
  366.  
  367. /* patch time */
  368. fixdate(s)
  369.     char *s;
  370. {
  371.     long time();
  372.     char buf[24];
  373.     int fd;
  374.  
  375.     fd = open(s, 1);
  376.     if(fd < 0) {
  377.         (void) fprintf(stderr, "ranlib: can't reopen %s\n", s);
  378.         return;
  379.     }
  380.     (void) sprintf(buf, "%-*ld", sizeof(archdr.ar_date), time((long *)NULL)+5);
  381.     (void) lseek(fd, (long)(SARMAG + ((char *)archdr.ar_date-(char *)&archdr)), 0);
  382.     (void) write(fd, buf, sizeof(archdr.ar_date));
  383.     (void) close(fd);
  384. }
  385.